package com.ycb.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycb.entity.User;
import com.ycb.mapper.UserMapper;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author 黄泽群
 * @since 2023-12-11
 */
@Slf4j
@Service
@LocalTCC
@RequiredArgsConstructor
public class UserService extends ServiceImpl<UserMapper, User> {

    @Transactional // 单数据源内部可以通过Transactional保证单节点事务
    @TwoPhaseBusinessAction(name = "subAmount",commitMethod = "subAmountCommit" , rollbackMethod = "subAmountRollback",isDelayReport = true,useTCCFence = true)
    public User subAmount(BusinessActionContext context,
                          @BusinessActionContextParameter("userId") Integer userId,
                          @BusinessActionContextParameter("subAmt") Integer subAmt) {
        log.warn(" UserService.subAmount xid :{} branchId:{} getActionContext:{}",context.getXid(),context.getBranchId()
                ,context.getActionContext());
        User user = super.getById(userId);
        if (user.getAmt() < subAmt){
            throw new RuntimeException("用户余额不足");
        }
        user.setAmt(user.getAmt() - subAmt);
        super.updateById(user);
        return user;
    }

    public void subAmountCommit(BusinessActionContext context){
        log.warn(" subAmountCommit xid :{} branchId:{} userId:{} subAmt:{}",context.getXid(),context.getBranchId()
                ,context.getActionContext("userId"),context.getActionContext("subAmt"));
        String xid = context.getXid();
    }

    public void subAmountRollback(BusinessActionContext context){
        log.warn(" subAmountRollback xid :{} branchId:{} userId:{} num:{}",context.getXid(),context.getBranchId()
                ,context.getActionContext("userId"),context.getActionContext("subAmt"));
        String xid = context.getXid();
        Integer userId = context.getActionContext("userId", Integer.class);
        Integer subAmt = context.getActionContext("subAmt", Integer.class);
        User user = super.getById(userId);
        user.setAmt(user.getAmt() + subAmt);
        super.updateById(user);
    }
}
